home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 5
/
The 640 Meg Shareware Studio CD-ROM Volume V (Data Express)(1994).ISO
/
amiga
/
mucnpd12.lha
/
MUI_Icon_Update.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-22
|
31KB
|
782 lines
/* MUI_Icon_Update.c
An application for use with MagicWB.
Copyright ⌐ 1994 by Robert Poole, all rights reserved
*/
/* MUI */
#include <libraries/mui.h>
/* System */
#include <dos.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <graphics/gfxmacros.h>
#include <workbench/workbench.h>
#include <exec/memory.h>
/* Prototypes */
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/icon_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/muimaster_protos.h>
#include <clib/asl_protos.h>
/* ANSI C */
#include <stdlib.h>
#include <string.h>
#include <math.h>
/* pragmas */
#include <pragmas/muimaster_pragmas.h>
/* version string */
#define MYVER "1.2"
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct Library *UtilityBase,*DOSBase,*IconBase,*AslBase,*IconBase,
*WorkbenchBase, *GadToolsBase;
static struct Library *MUIMasterBase = NULL;
/* function prototypes */
static VOID fail(APTR, char *);
static VOID init(VOID);
__saveds __asm LONG AppMsgFunc(register __a2 APTR, register __a1 struct AppMessage **);
#ifdef FUTURE
__saveds __asm LONG AppMsgFunc2(register __a2 APTR, register __a1 struct AppMessage **);
#endif
APTR Create_Window(struct DiskObject *dobj);
struct Image *Augment_Image(struct Image *);
void Free_Augmented_Image(struct Image *);
__saveds __asm APTR source_rxfunc(register __a0 struct Hook *,
register __a2 Object *, register __a1 ULONG *);
__saveds __asm APTR target_rxfunc(register __a0 struct Hook *,
register __a2 Object *, register __a1 ULONG *);
char *IconName(char *);
/*************************/
/* Init & Fail Functions */
/*************************/
static VOID fail(APTR app,char *str)
{
if (str) {
/* This *should* work OK -- if app is NULL, it'll default to
a standard system requester */
if (MUIMasterBase) {
MUI_Request(app, NULL, 0, NULL, "OK", str);
}
else {
BPTR fh;
/* write str to a CONsole */
fh = Open("CON:0/0/400/100/Error Message/AUTO/WAIT", MODE_NEWFILE);
Write(fh, str, strlen(str));
Close(fh);
}
}
if (app)
MUI_DisposeObject(app);
if (MUIMasterBase)
CloseLibrary(MUIMasterBase);
if (str) {
exit(20);
}
else {
exit(0);
}
}
static VOID init(VOID)
{
if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN)))
fail(NULL,"Failed to open "MUIMASTER_NAME".");
}
/* Hook function to put dropped icons into string gadget */
__saveds __asm LONG AppMsgFunc(register __a2 APTR obj, register __a1 struct AppMessage **x)
{
struct WBArg *ap;
struct AppMessage *amsg = *x;
int i;
static char buf[256];
for (ap = amsg->am_ArgList, i = 0; i < amsg->am_NumArgs; i++, ap++) {
NameFromLock(ap->wa_Lock, buf, sizeof(buf));
AddPart(buf, ap->wa_Name, sizeof(buf));
/* if it's a directory, clobber '/' at end */
if (buf[strlen(buf) - 1] == '/') {
buf[strlen(buf) - 1] = '\0';
}
set(obj, MUIA_String_Contents, buf);
}
return(0);
}
static struct Hook AppMsgFuncHook = {
{NULL, NULL}, (VOID *) AppMsgFunc, NULL, NULL
};
/* Hook function to put dropped icons into image object */
#ifdef FUTURE
__saveds __asm LONG AppMsgFunc2(register __a2 APTR obj, register __a1 struct AppMessage **x)
{
struct WBArg *ap;
struct AppMessage *amsg = *x;
int i;
static char buf[256];
struct DiskObject *temp;
set(obj, MUIA_ShowMe, FALSE);
for (ap = amsg->am_ArgList, i = 0; i < amsg->am_NumArgs; i++, ap++) {
NameFromLock(ap->wa_Lock, buf, sizeof(buf));
AddPart(buf, ap->wa_Name, sizeof(buf));
/* Now do a GetDiskObjectNew()... */
temp = GetDiskObjectNew(buf);
set(obj, MUIA_Image_OldImage, temp->do_Gadget.GadgetRender);
}
set(obj, MUIA_ShowMe, TRUE);
return(0);
}
static struct Hook AppMsgFuncHook2 = {
{NULL, NULL}, (VOID *) AppMsgFunc2, NULL, NULL
};
#endif
#ifndef MAKE_ID
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#endif
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
LONG __stack = 20000L;
char *__procname = "MUI_Icon_Update_process";
long __oslibversion = 37L;
static Object *App; /* Application object */
static Object *WI_main;
static Object *CK_Tool_Types; /* Preserve tooltypes? */
static Object *CK_Icon_Position; /* Preserve icon position? */
static Object *CK_Stack_Size; /* Preserve stack size? */
static Object *CK_Default_Tool; /* Preserve default tool? */
static Object *CK_Window_Position; /* Preserve window position? */
static Object *CK_Repair_Structure; /* Repair icon to display correctly? */
static Object *PO_Source; /* source icon */
static Object *ST_Source;
static Object *IM_Source; /* source image */
static Object *PO_Target; /* target icon */
static Object *ST_Target;
static Object *IM_Target; /* target image */
static Object *BT_Start; /* start the conversion */
typedef enum {ID_dummy, ID_start, ID_about, ID_quit, ID_perform,
ID_results} IDVal;
/* Hook functions for ARexx */
__saveds __asm APTR source_rxfunc(register __a0 struct Hook *hook,
register __a2 Object *app, register __a1 ULONG *arg)
{
char *fname;
if (fname = (char *)*arg) {
set(ST_Source, MUIA_String_Contents, fname);
}
return(RETURN_OK);
}
static struct Hook source_rxhook = {
{NULL, NULL}, (void *) source_rxfunc, NULL, NULL
};
__saveds __asm APTR target_rxfunc(register __a0 struct Hook *hook,
register __a2 Object *app, register __a1 ULONG *arg)
{
char *fname;
if (fname = (char *)*arg) {
set(ST_Target, MUIA_String_Contents, fname);
}
return(RETURN_OK);
}
static struct Hook target_rxhook = {
{NULL, NULL}, (void *) target_rxfunc, NULL, NULL
};
__saveds __asm APTR query_rxfunc(register __a0 struct Hook *hook,
register __a2 Object *app, register __a1 ULONG *arg)
{
char *gadget;
ULONG checked;
Object *temp;
if (gadget = (char *)*arg) {
switch (gadget[0]) {
case 't':
case 'T':
temp = CK_Tool_Types;
break;
case 'i':
case 'I':
temp = CK_Icon_Position;
break;
case 's':
case 'S':
temp = CK_Stack_Size;
break;
case 'd':
case 'D':
temp = CK_Default_Tool;
break;
case 'w':
case 'W':
temp = CK_Window_Position;
break;
case 'r':
case 'R':
temp = CK_Repair_Structure;
break;
default:
return(RETURN_OK);
break;
}
get(temp, MUIA_Selected, &checked);
set(app, MUIA_Application_RexxString,
(checked ? "true" : "false"));
}
return(RETURN_OK);
}
static struct Hook query_rxhook = {
{NULL, NULL}, (void *) query_rxfunc, NULL, NULL
};
__saveds __asm APTR toggle_rxfunc(register __a0 struct Hook *hook,
register __a2 Object *app, register __a1 ULONG *arg)
{
char *gadget;
ULONG checked;
Object *temp;
if (gadget = (char *)*arg) {
switch (gadget[0]) {
case 't':
case 'T':
temp = CK_Tool_Types;
break;
case 'i':
case 'I':
temp = CK_Icon_Position;
break;
case 's':
case 'S':
temp = CK_Stack_Size;
break;
case 'd':
case 'D':
temp = CK_Default_Tool;
break;
case 'w':
case 'W':
temp = CK_Window_Position;
break;
case 'r':
case 'R':
temp = CK_Repair_Structure;
break;
default:
return(RETURN_OK);
break;
}
get(temp, MUIA_Selected, &checked);
set(temp, MUIA_Selected, !checked);
set(app, MUIA_Application_RexxString,
(!checked ? "true" : "false"));
}
return(RETURN_OK);
}
static struct Hook toggle_rxhook = {
{NULL, NULL}, (void *) toggle_rxfunc, NULL, NULL
};
#ifdef SLEEP_IMAGE
extern struct DiskObject sleepimg;
#endif
extern struct DiskObject drophere;
static struct DiskObject *source, *target, *synthetic;
/* Menus for all windows. */
static struct NewMenu menu_list[] =
{
{NM_TITLE, "Project", 0, 0, 0, 0
},
{NM_ITEM, "Perform", "P", 0, 0, (APTR) ID_start
},
{NM_ITEM, NM_BARLABEL, 0, 0, 0, 0
},
{NM_ITEM, "About", "?", 0, 0, (APTR) ID_about
},
{NM_ITEM, NM_BARLABEL, 0, 0, 0, 0
},
{NM_ITEM, "Quit", "Q", 0, 0, (APTR) ID_quit
},
{NM_TITLE, "Settings", 0, 0, 0, 0
},
{NM_ITEM, "Display Results?", 0, CHECKIT|CHECKED|MENUTOGGLE, 0,
(APTR) ID_results},
{NM_END, NULL, 0, 0, 0, 0
},
};
/* ARexx commands */
static struct MUI_Command arexx_list[] =
{
{"perform", MC_TEMPLATE_ID, ID_perform, NULL
},
{"source", "SOURCEFILE/A", 1, &source_rxhook
},
{"target", "TARGETFILE/A", 1, &target_rxhook
},
{"toggle", "GADNAME/A", 1, &toggle_rxhook
},
{"query", "GADNAME/A", 1, &query_rxhook
},
{NULL, NULL, 0, NULL
}
};
int main(void)
{
BOOL running = TRUE, uses_rexx = FALSE, show_results = TRUE;
ULONG signal = 0, status = 0, active = 0, checked = 0;
char *fname, *fname_icon;
BPTR file_lock;
struct FileInfoBlock *fib;
LONG oldbits;
init();
fib = AllocDosObjectTags(DOS_FIB,
TAG_DONE);
/* start creating the application */
App = ApplicationObject,
MUIA_Application_Title, "Icon_Update",
MUIA_Application_Version, "$VER: MUI Icon Update "MYVER" "__AMIGADATE__,
MUIA_Application_Copyright, "Copyright ⌐ 1994 Robert Poole",
MUIA_Application_Author, "Robert Poole",
MUIA_Application_Description, "MagicWB icon update / repair program",
MUIA_Application_Base, "ICONUPD",
MUIA_Application_Menu, menu_list,
MUIA_Application_Commands, arexx_list,
#ifdef SLEEP_IMAGE
MUIA_Application_DiskObject, &sleepimg,
#else
MUIA_Application_DiskObject, &drophere,
#endif
SubWindow, WI_main = Create_Window(&drophere),
End;
if (!App) fail(App, "Failed to create application.");
/* close window when close gadget is hit */
DoMethod(WI_main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App, 2,
MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
/* automagically put name of file into string gad when icon dropped on image */
DoMethod(IM_Source, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
ST_Source, 3, MUIM_CallHook, &AppMsgFuncHook, MUIV_TriggerValue);
DoMethod(IM_Target, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
ST_Target, 3, MUIM_CallHook, &AppMsgFuncHook, MUIV_TriggerValue);
#ifdef FUTURE
/* automagically put image of icon into image object when dropped */
DoMethod(IM_Source, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
IM_Source, 3, MUIM_CallHook, &AppMsgFuncHook2, MUIV_TriggerValue);
DoMethod(IM_Target, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
IM_Target, 3, MUIM_CallHook, &AppMsgFuncHook2, MUIV_TriggerValue);
#endif
/* when iconified, target gets messages from icons dropped on
AppIcon */
set(App, MUIA_Application_DropObject, IM_Target);
/* return value for START button */
DoMethod(BT_Start, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
MUIM_Application_ReturnID, ID_start);
/* open the window */
set(WI_main, MUIA_Window_Open, TRUE);
get(WI_main, MUIA_Window_Open, &status);
if (!status) {
fail(App, "Failed to open window.");
}
while (running) {
switch (DoMethod(App, MUIM_Application_Input, &signal)) {
case ID_quit:
case MUIV_Application_ReturnID_Quit:
get(PO_Source, MUIA_Popasl_Active, &active);
if (!active) get(PO_Target, MUIA_Popasl_Active, &active);
if (active) {
MUI_Request(App, WI_main, 0, NULL, "OK",
"Can't quit, ASL popups still open.");
}
else {
running = FALSE;
}
break;
case ID_about:
MUI_Request(App, WI_main, 0, NULL, "OK",
"MUI Icon Update\n\n"
"Version "MYVER"\n"
"Compiled "__DATE__"\n"
"Copyright ⌐ 1994 Robert Poole\n\n"
"MUI is Copyright ⌐ 1993, 1994\n"
"by Stefan Stuntz",
TAG_END);
break;
case ID_results:
show_results = (!show_results);
break;
case ID_perform:
uses_rexx = TRUE;
/* falls through to... */
case ID_start:
get(ST_Source, MUIA_String_Contents, &fname);
if (strlen(fname) == 0)
break;
source = GetDiskObjectNew(fname);
if (source == NULL) {
MUI_Request(App, WI_main, 0, NULL, "OK",
"Can't read source.");
break;
}
get(ST_Target, MUIA_String_Contents, &fname);
if (strlen(fname) == 0) {
FreeDiskObject(source);
break;
}
/* We want to be able to update icons of
write-protected files. */
fname_icon = IconName(fname);
file_lock = Lock(fname_icon, ACCESS_READ);
if (file_lock == NULL) {
fname_icon = fname;
file_lock = Lock(fname, ACCESS_READ);
if (file_lock == NULL) {
/* tell user we can't do it */
MUI_Request(App, WI_main, 0, NULL, "OK",
"Can't obtain file lock.");
FreeDiskObject(source);
break;
}
}
if (Examine(file_lock, fib)) {
oldbits = fib->fib_Protection;
if (oldbits & FIBF_WRITE) {
if (!SetProtection(fname_icon, oldbits & (~FIBF_WRITE))) {
MUI_Request(App, WI_main, 0, NULL, "OK",
"Can't reset Write bit.");
}
}
}
else {
oldbits = -1;
MUI_Request(App, WI_main, 0, NULL, "OK",
"Warning: Can't examine protection bits.");
}
target = GetDiskObjectNew(fname);
synthetic = (struct DiskObject *) AllocMem(sizeof(struct DiskObject),
MEMF_PUBLIC | MEMF_CLEAR);
synthetic->do_Magic = source->do_Magic;
synthetic->do_Version = source->do_Version;
synthetic->do_Gadget = source->do_Gadget;
synthetic->do_Type = source->do_Type;
get(CK_Tool_Types, MUIA_Selected, &checked);
if (checked) {
synthetic->do_ToolTypes = target->do_ToolTypes;
}
else {
synthetic->do_ToolTypes = source->do_ToolTypes;
}
get(CK_Icon_Position, MUIA_Selected, &checked);
if (checked) {
synthetic->do_CurrentX = target->do_CurrentX;
synthetic->do_CurrentY = target->do_CurrentY;
}
else {
synthetic->do_CurrentX = NO_ICON_POSITION;
synthetic->do_CurrentY = NO_ICON_POSITION;
}
get(CK_Stack_Size, MUIA_Selected, &checked);
if (checked) {
synthetic->do_StackSize = target->do_StackSize;
}
else {
synthetic->do_StackSize = 8192;
}
get(CK_Default_Tool, MUIA_Selected, &checked);
if (checked) {
synthetic->do_DefaultTool = target->do_DefaultTool;
}
else {
synthetic->do_DefaultTool = source->do_DefaultTool;
}
get(CK_Window_Position, MUIA_Selected, &checked);
if (checked) {
synthetic->do_DrawerData = target->do_DrawerData;
}
else {
synthetic->do_DrawerData = NULL;
}
get(CK_Repair_Structure, MUIA_Selected, &checked);
if (checked) {
synthetic->do_Gadget.GadgetRender =
Augment_Image(source->do_Gadget.GadgetRender);
if ((source->do_Gadget.Flags) & GFLG_GADGHIMAGE) {
synthetic->do_Gadget.SelectRender =
Augment_Image(source->do_Gadget.SelectRender);
}
}
/* Before we PutDiskObject(), let's Unlock() */
UnLock(file_lock);
/* now write out the icon */
if (PutDiskObject(fname, synthetic)) {
if (!uses_rexx && show_results) {
MUI_Request(App, WI_main, 0, NULL, "OK",
"Update Successful.");
}
else {
uses_rexx = FALSE;
}
}
else {
MUI_Request(App, WI_main, 0, NULL, "OK",
"Error! Can't update icon.");
}
/* now reset the protection bits */
if (oldbits != -1) {
SetProtection(fname_icon, oldbits);
}
/* OK, if we have "repaired" the imagery, we must
deallocate resources. */
if (checked) {
Free_Augmented_Image(synthetic->do_Gadget.GadgetRender);
if ((source->do_Gadget.GadgetType) & GFLG_GADGHIMAGE) {
Free_Augmented_Image(synthetic->do_Gadget.SelectRender);
}
}
/* now free up the synthetic disk object */
FreeMem((void *) synthetic, sizeof(struct DiskObject));
/* and free the DiskObjects */
FreeDiskObject(source);
FreeDiskObject(target);
break;
default:
break;
}
if (running && signal) {
Wait(signal);
}
}
FreeDosObject(DOS_FIB, fib);
fail(App, NULL);
}
/* End: main() */
APTR Create_Window(struct DiskObject *dobj)
{
return (
WindowObject,
MUIA_Window_ID, MAKE_ID('I','C','O','U'),
MUIA_Window_Title, "MUI Icon Update",
MUIA_Window_AppWindow, TRUE,
WindowContents, HGroup,
Child, VGroup,
Child, HGroup,
Child, RectangleObject, End,
Child, IM_Source = ImageObject,
TextFrame,
MUIA_Image_OldImage, dobj->do_Gadget.GadgetRender,
End,
Child, RectangleObject, End,
End,
Child, ColGroup(2),
Child, KeyLabel2("Source:",'s'),
Child, PO_Source = PopaslObject,
MUIA_Popstring_String, ST_Source = KeyString(0, 256, 's'),
MUIA_Popstring_Button, PopButton(MUII_PopFile),
ASLFR_TitleText, "Please select source icon",
ASLFR_DoPatterns, TRUE,
ASLFR_InitialPattern, "~(#?.info)",
End,
End,
Child, HGroup,
Child, RectangleObject, End,
Child, IM_Target = ImageObject,
TextFrame,
MUIA_Image_OldImage, drophere.do_Gadget.GadgetRender,
End,
Child, RectangleObject, End,
End,
Child, ColGroup(2),
Child, KeyLabel2("Target:",'t'),
Child, PO_Target = PopaslObject,
MUIA_Popstring_String, ST_Target = KeyString(0, 256, 't'),
MUIA_Popstring_Button, PopButton(MUII_PopFile),
ASLFR_TitleText, "Please select target icon",
ASLFR_DoPatterns, TRUE,
ASLFR_InitialPattern, "~(#?.info)",
End,
End,
Child, HGroup,
Child, RectangleObject,
MUIA_HorizWeight, 300,
End,
Child, BT_Start = KeyButton("Start",'r'),
End,
End,
Child, RectangleObject,
MUIA_Rectangle_VBar, TRUE,
MUIA_FixWidth, 8,
End,
Child, VGroup,
Child, ColGroup(2),
MUIA_Frame, MUIV_Frame_None,
MUIA_FrameTitle, "Preserve:",
Child, CK_Tool_Types = CheckMark(TRUE),
Child, LLabel1("Tool Types"),
Child, CK_Icon_Position = CheckMark(TRUE),
Child, LLabel1("Icon Position"),
Child, CK_Stack_Size = CheckMark(TRUE),
Child, LLabel1("Stack Size"),
Child, CK_Default_Tool = CheckMark(TRUE),
Child, LLabel1("Default Tool"),
Child, CK_Window_Position = CheckMark(TRUE),
Child, LLabel1("Window Position"),
End,
Child, RectangleObject,
MUIA_Rectangle_HBar, TRUE,
MUIA_FixHeight, 6,
End,
Child, ColGroup(2),
Child, CK_Repair_Structure = CheckMark(FALSE),
Child, LLabel1("Repair Icon Structure"),
End,
End,
End,
End
);
}
/* End: CreateWindow() */
/* The following function takes a struct Image as input and returns a
similar structure that has been augmented to display correctly under
Amigados 3.0. This is accomplished by taking bitplane 2 and dupli-
cating it to create bitplanes 3 through 7. */
struct Image *Augment_Image(struct Image *source)
{
struct Image *temp;
ULONG planesize, copydepth;
register ULONG i;
/* step 1 -- allocate a temp image structure */
temp = (struct Image *) AllocMem(sizeof(struct Image),
MEMF_PUBLIC | MEMF_CLEAR);
/* step 2 -- start copying contents of source to temp */
temp->LeftEdge = source->LeftEdge;
temp->TopEdge = source->TopEdge;
temp->Width = source->Width;
temp->Height = source->Height;
/* we are creating an 8-bitplane image */
temp->Depth = 8;
/* as such, we change PlanePick to be what we want */
temp->PlanePick = 0x00FF;
temp->PlaneOnOff = 0x0000;
temp->NextImage = NULL;
/* step 3 -- create an array of UWORD the size we need */
planesize = ((source->Width + 15) / 16) * (source->Height);
temp->ImageData = (UWORD *) AllocVec(sizeof(UWORD) * planesize * 8,
MEMF_CHIP | MEMF_CLEAR);
/* step 4 -- copy bitplanes that exist */
copydepth = (source->Depth > 3 ? 3 : source->Depth);
for (i = 0; i < planesize * copydepth; i++) {
temp->ImageData[i] = source->ImageData[i];
}
/* OK, if copydepth < 3, we're done, otherwise keep going! */
if (copydepth < 3) {
return(temp);
}
else {
/* duplicate bitplane 2 repeatedly */
for (i = 0; i < planesize * 5; i++) {
temp->ImageData[i + planesize*3] =
source->ImageData[(i % planesize) + planesize*2];
}
return(temp);
}
}
/* end: Augment_Image() */
/* anything allocated with Augment_Image() must be deallocated... */
void Free_Augmented_Image(struct Image *img)
{
FreeVec(img->ImageData);
FreeMem((void *) img, sizeof(struct Image));
}
/* end: Free_Augmented_Image() */
/* Append .info extension to a file name. */
char *IconName(char *fname)
{
static char buf[256];
strcpy(buf, fname);
return(strcat(buf, ".info"));
}
/* end: IconName() */